diff options
38 files changed, 529 insertions, 83 deletions
diff --git a/doc/src/classes/phonon-api.qdoc b/doc/src/classes/phonon-api.qdoc index 98df89d..641b936 100644 --- a/doc/src/classes/phonon-api.qdoc +++ b/doc/src/classes/phonon-api.qdoc @@ -1651,6 +1651,16 @@ playback of the current source, but it is possible to try with a different one. A user readable error message is given by errorString(). + \section1 Symbian Platform Security Requirements + + On Symbian, processes which access media via the network must + have the \c NetworkServices platform security capability. If the client + process lacks this capability, operations will result in errors. + This failure is indicated by a state() of Phonon::ErrorState. + + Platform security capabilities are added via the + \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY} + qmake variable. \sa Phonon::MediaSource, Phonon::AudioOutput, VideoWidget, {Music Player Example}, {Phonon Overview}, Phonon::VideoPlayer, diff --git a/doc/src/platforms/platform-notes.qdoc b/doc/src/platforms/platform-notes.qdoc index f513181..131d035 100644 --- a/doc/src/platforms/platform-notes.qdoc +++ b/doc/src/platforms/platform-notes.qdoc @@ -502,6 +502,31 @@ For information about mixing exceptions with Symbian leaves, see \l{Exception Safety with Symbian}. + \section1 Required Capabilities + + Distributions of Qt are typically signed with \c{All -TCB}. What your + application needs to be signed with in order to function with Qt depends + on what functionality it uses: + + \table + \header \o Technology + \o Required Symbian Capability + \row \o QtCore + \o \c PowerMgmt if applications are terminated using QProcess. + \row \o QtNetwork + \o NetworkServices + \row \o QtMultiMedia + \o \c UserEnvironment if QAudioInput is used. + \endtable + + Depending on what file paths that are accessed and how AllFiles may be + required. Similarly, if the network is accessed indirectly through + components such as QtXmlPatterns, QtWebkit or QtScript, the capabilities + needs to match accordingly. + + See individual classes' documentation for specifics. If a class does not + mention Symbian capabilities, it requires none. + \section1 Multimedia and Phonon Support Qt provides a backend for Qt's Phonon module, which supports diff --git a/mkspecs/aix-xlc-64/qmake.conf b/mkspecs/aix-xlc-64/qmake.conf index a18aa9f..72eef89 100644 --- a/mkspecs/aix-xlc-64/qmake.conf +++ b/mkspecs/aix-xlc-64/qmake.conf @@ -48,7 +48,7 @@ QMAKE_LIBDIR_OPENGL = QMAKE_LINK = xlC QMAKE_LINK_THREAD = xlC_r QMAKE_LINK_SHLIB = ld -QMAKE_LFLAGS = -q64 +QMAKE_LFLAGS = -q64 -bbigtoc QMAKE_LFLAGS_RELEASE = QMAKE_LFLAGS_DEBUG = QMAKE_LFLAGS_SHLIB = -qmkshrobj diff --git a/mkspecs/aix-xlc/qmake.conf b/mkspecs/aix-xlc/qmake.conf index 42f6f7e..f4d77e5 100644 --- a/mkspecs/aix-xlc/qmake.conf +++ b/mkspecs/aix-xlc/qmake.conf @@ -48,7 +48,7 @@ QMAKE_LIBDIR_OPENGL = QMAKE_LINK = xlC QMAKE_LINK_THREAD = xlC_r QMAKE_LINK_SHLIB = ld -QMAKE_LFLAGS = +QMAKE_LFLAGS = -bmaxdata:0x80000000 QMAKE_LFLAGS_RELEASE = QMAKE_LFLAGS_DEBUG = QMAKE_LFLAGS_SHLIB = -qmkshrobj diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index cf32685..62cce62 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -166,8 +166,14 @@ for(QTLIB, $$list($$lower($$unique(QT)))) { # we bump the values for all Symbian Phonon plugins. symbian:isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x040000 0x1600000 - } else:isEqual(QTLIB, webkit):qlib = QtWebKit - else:isEqual(QTLIB, declarative):qlib = QtDeclarative + } else:isEqual(QTLIB, webkit) { + qlib = QtWebKit + aix-xlc { + # Flags recommended by IBM when using WebKit + QMAKE_LFLAGS -= -bmaxdata:0x80000000 + QMAKE_LFLAGS += -bmaxdata:0xD0000000/dsa + } + } else:isEqual(QTLIB, declarative):qlib = QtDeclarative else:isEqual(QTLIB, multimedia):qlib = QtMultimedia else:message("Unknown QT: $$QTLIB"):qlib = !isEmpty(qlib) { diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp index 1014ba2..9f3f5c3 100644 --- a/qmake/generators/symbian/symmake_sbsv2.cpp +++ b/qmake/generators/symbian/symmake_sbsv2.cpp @@ -75,7 +75,7 @@ void SymbianSbsv2MakefileGenerator::exportFlm() foreach(QFileInfo item, sourceInfos) { QFileInfo destInfo = QFileInfo(destDir.absolutePath() + "/" + item.fileName()); - if (!destInfo.exists() || destInfo.lastModified() < item.lastModified()) { + if (!destInfo.exists() || destInfo.lastModified() != item.lastModified()) { if (destInfo.exists()) QFile::remove(destInfo.absoluteFilePath()); if (QFile::copy(item.absoluteFilePath(), destInfo.absoluteFilePath())) diff --git a/qmake/qmake.pri b/qmake/qmake.pri index 05debe6..b82ab4d 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -130,6 +130,7 @@ bootstrap { #Qt code } else:win32 { SOURCES += qfsfileengine_win.cpp qfsfileengine_iterator_win.cpp qsettings_win.cpp win32-msvc*:LIBS += ole32.lib advapi32.lib + win32-g++:LIBS += -lole32 -luuid } qnx { diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 12a992a..af1fc82 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -551,6 +551,16 @@ void QProcessPrivate::Channel::clear() interpreter itself (\c{cmd.exe} on some Windows systems), and ask the interpreter to execute the desired command. + \section1 Symbian Platform Security Requirements + + On Symbian, processes which use the functions kill() or terminate() + must have the \c PowerMgmt platform security capability. If the client + process lacks this capability, these functions will fail. + + Platform security capabilities are added via the + \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY} + qmake variable. + \sa QBuffer, QFile, QTcpSocket */ @@ -2006,9 +2016,13 @@ void QProcess::start(const QString &program, OpenMode mode) event loop does not handle the WM_CLOSE message, can only be terminated by calling kill(). + On Symbian, this function requires platform security capability + \c PowerMgmt. If absent, the process will panic with KERN-EXEC 46. + \note Terminating running processes from other processes will typically cause a panic in Symbian due to platform security. + \sa \l {Symbian Platform Security Requirements} \sa kill() */ void QProcess::terminate() @@ -2023,6 +2037,10 @@ void QProcess::terminate() On Windows, kill() uses TerminateProcess, and on Unix and Mac OS X, the SIGKILL signal is sent to the process. + On Symbian, this function requires platform security capability + \c PowerMgmt. If absent, the process will panic with KERN-EXEC 46. + + \sa \l {Symbian Platform Security Requirements} \sa terminate() */ void QProcess::kill() diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index ca44264..8c96057 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -570,7 +570,13 @@ void QSelectThread::updateActivatedNotifiers(QSocketNotifier::Type type, fd_set * check if socket is in exception set * then signal RequestComplete for it */ - qWarning("exception on %d", i.key()->socket()); + qWarning("exception on %d [will close the socket handle - hack]", i.key()->socket()); + // quick fix; there is a bug + // when doing read on socket + // errors not preoperly mapped + // after offline-ing the device + // on some devices we do get exception + ::close(i.key()->socket()); toRemove.append(i.key()); TRequestStatus *status = i.value(); QEventDispatcherSymbian::RequestComplete(d->threadData->symbian_thread_handle, status, KErrNone); diff --git a/src/gui/embedded/qscreenqnx_qws.cpp b/src/gui/embedded/qscreenqnx_qws.cpp index 705db7e..a0a697f 100644 --- a/src/gui/embedded/qscreenqnx_qws.cpp +++ b/src/gui/embedded/qscreenqnx_qws.cpp @@ -205,7 +205,7 @@ static bool createMemSurface(QQnxScreenContext * const d, int w, int h) int ret = gf_surface_create(&d->memSurface, d->device, w, h, GF_FORMAT_ARGB8888, 0, GF_SURFACE_CREATE_CPU_FAST_ACCESS | GF_SURFACE_CREATE_CPU_LINEAR_ACCESSIBLE - | GF_SURFACE_PHYS_CONTIG); + | GF_SURFACE_PHYS_CONTIG | GF_SURFACE_CREATE_SHAREABLE); if (ret != GF_ERR_OK) { qWarning("QQnxScreen: gf_surface_create(%dx%d) failed with error code %d", w, h, ret); diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index cc60246..94036d0 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -58,6 +58,11 @@ // MAknEdStateObserver::EAknActivatePenInputRequest #define QT_EAknActivatePenInputRequest MAknEdStateObserver::EAknEdwinStateEvent(7) +// EAknEditorFlagSelectionVisible is only valid from 3.2 onwards. +// Sym^3 AVKON FEP manager expects that this flag is used for FEP-aware editors +// that support text selection. +#define QT_EAknEditorFlagSelectionVisible 0x100000 + QT_BEGIN_NAMESPACE QCoeFepInputContext::QCoeFepInputContext(QObject *parent) @@ -75,7 +80,10 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent) m_hasTempPreeditString(false) { m_fepState->SetObjectProvider(this); - m_fepState->SetFlags(EAknEditorFlagDefault); + if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) + m_fepState->SetFlags(EAknEditorFlagDefault | QT_EAknEditorFlagSelectionVisible); + else + m_fepState->SetFlags(EAknEditorFlagDefault); m_fepState->SetDefaultInputMode( EAknEditorTextInputMode ); m_fepState->SetPermittedInputModes( EAknEditorAllInputModes ); m_fepState->SetDefaultCase( EAknEditorLowerCase ); @@ -432,7 +440,10 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints) m_fepState->SetPermittedCases(flags); ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate); - flags = 0; + if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) + flags = QT_EAknEditorFlagSelectionVisible; + else + flags = 0; if (hints & ImhUppercaseOnly && !(hints & ImhLowercaseOnly) || hints & ImhLowercaseOnly && !(hints & ImhUppercaseOnly)) { flags |= EAknEditorFlagFixedCase; diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index f49acc4..28cbc45 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -122,6 +122,8 @@ QPalette *QS60StylePrivate::m_themePalette = 0; qint64 QS60StylePrivate::m_webPaletteKey = 0; +QPointer<QWidget> QS60StylePrivate::m_pressedWidget = 0; + const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameElementsData[] = { {SE_ButtonNormal, QS60StyleEnums::SP_QsnFrButtonTbCenter}, {SE_ButtonPressed, QS60StyleEnums::SP_QsnFrButtonTbCenterPressed}, @@ -138,6 +140,8 @@ const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameEleme {SE_PanelBackground, QS60StyleEnums::SP_QsnFrSetOptCenter}, {SE_ButtonInactive, QS60StyleEnums::SP_QsnFrButtonCenterInactive}, {SE_Editor, QS60StyleEnums::SP_QsnFrInputCenter}, + {SE_TableItemPressed, QS60StyleEnums::SP_QsnFrGridCenterPressed}, + {SE_ListItemPressed, QS60StyleEnums::SP_QsnFrListPressed}, }; static const int frameElementsCount = @@ -294,6 +298,12 @@ void QS60StylePrivate::drawSkinElement(SkinElements element, QPainter *painter, case SE_DropArea: drawPart(QS60StyleEnums::SP_QgnGrafOrgBgGrid, painter, rect, flags | SF_PointNorth); break; + case SE_TableItemPressed: + drawFrame(SF_TableItemPressed, painter, rect, flags | SF_PointNorth); + break; + case SE_ListItemPressed: + drawFrame(SF_ListItemPressed, painter, rect, flags | SF_PointNorth); + break; default: break; } @@ -939,6 +949,11 @@ bool QS60StylePrivate::canDrawThemeBackground(const QBrush &backgroundBrush, con backgroundBrush.style() == Qt::NoBrush) ? true : false; } +bool QS60StylePrivate::isWidgetPressed(const QWidget *widget) +{ + return (widget && widget == m_pressedWidget); +} + /*! \class QS60Style \brief The QS60Style class provides a look and feel suitable for applications on S60. @@ -1424,73 +1439,37 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, // draw themed background for table unless background brush has been defined. if (vopt->backgroundBrush == Qt::NoBrush) { if (itemView) { - 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 indexLast = itemView->model()->index( - 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()); drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget); } } else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget);} - // draw the focus rect - if (isSelected || hasFocus ) { - QRect highlightRect = option->rect.adjusted(1,1,-1,-1); - QAbstractItemView::SelectionBehavior selectionBehavior = - itemView ? itemView->selectionBehavior() : QAbstractItemView::SelectItems; - if (selectionBehavior != QAbstractItemView::SelectItems) { - // set highlight rect so that it is continuous from cell to cell, yet sligthly - // smaller than cell rect - int xBeginning = 0, yBeginning = 0, xEnd = 0, yEnd = 0; - if (selectionBehavior == QAbstractItemView::SelectRows) { - yBeginning = 1; yEnd = -1; - if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning) - xBeginning = 1; - else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End) - xEnd = -1; - } else if (selectionBehavior == QAbstractItemView::SelectColumns) { - xBeginning = 1; xEnd = -1; - if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning) - yBeginning = 1; - else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End) - yEnd = -1; - } - highlightRect = option->rect.adjusted(xBeginning, yBeginning, xEnd, yEnd); - } - if (vopt->showDecorationSelected && - (vopt->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color())) - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, highlightRect, flags); - else - painter->fillRect(highlightRect, vopt->palette.highlight()); - } - // draw the icon const QIcon::Mode mode = (voptAdj.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled; - const QIcon::State state = voptAdj.state & State_Open ? QIcon::On : QIcon::Off; + const QIcon::State state = (voptAdj.state & State_Open) ? QIcon::On : QIcon::Off; voptAdj.icon.paint(painter, iconRect, voptAdj.decorationAlignment, mode, state); // Draw selection check mark. Show check mark only in multi selection modes. if (itemView) { const bool singleSelection = (itemView->selectionMode() == QAbstractItemView::SingleSelection || - itemView->selectionMode() == QAbstractItemView::NoSelection); + itemView->selectionMode() == QAbstractItemView::NoSelection)|| + (itemView->selectionModel()->selectedIndexes().count() < 2 ); + + const bool selectItemsOnly = (itemView->selectionBehavior() == QAbstractItemView::SelectItems); + const QRect selectionRect = subElementRect(SE_ItemViewItemCheckIndicator, &voptAdj, widget); QStyleOptionViewItemV4 checkMarkOption(voptAdj); - // Draw selection mark. - if (voptAdj.state & State_Selected && !singleSelection) { + if (selectionRect.isValid()) checkMarkOption.rect = selectionRect; - drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); - if ( textRect.right() > selectionRect.left() ) + // Draw selection mark. + if (isSelected && !singleSelection && selectItemsOnly) { + proxy()->drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); + // @todo: this should happen in the rect retrievel i.e. subElementRect() + if (textRect.right() > selectionRect.left()) textRect.setRight(selectionRect.left()); } else if (singleSelection && - voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator && - selectionRect.isValid()) { - checkMarkOption.rect = selectionRect; + voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator) { checkMarkOption.state = checkMarkOption.state & ~State_HasFocus; switch (vopt->checkState) { @@ -2037,7 +2016,10 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti if (option->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color()) if ((qstyleoption_cast<const QStyleOptionFocusRect *>(option) && (qobject_cast<const QRadioButton *>(widget) || qobject_cast<const QCheckBox *>(widget)))) - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags); + QS60StylePrivate::drawSkinElement( + QS60StylePrivate::isWidgetPressed(widget) ? + QS60StylePrivate::SE_ListItemPressed : + QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags); else commonStyleDraws = true; } @@ -2257,6 +2239,57 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti break; #ifndef QT_NO_ITEMVIEWS case PE_PanelItemViewItem: + if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) { + const bool isSelected = (vopt->state & State_Selected); + const bool hasFocus = (vopt->state & State_HasFocus); + const bool isPressed = QS60StylePrivate::isWidgetPressed(widget); + + if (option->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color()) { + QRect highlightRect = vopt->rect.adjusted(1,1,-1,-1); + const QAbstractItemView *itemView = qobject_cast<const QAbstractItemView *>(widget); + QAbstractItemView::SelectionBehavior selectionBehavior = + itemView ? itemView->selectionBehavior() : QAbstractItemView::SelectItems; + // Set the draw area for highlights (focus, select rect or pressed rect) + if (hasFocus || isSelected || isPressed) { + if (selectionBehavior != QAbstractItemView::SelectItems) { + // set highlight rect so that it is continuous from cell to cell, yet sligthly + // smaller than cell rect + int xBeginning = 0, yBeginning = 0, xEnd = 0, yEnd = 0; + if (selectionBehavior == QAbstractItemView::SelectRows) { + yBeginning = 1; yEnd = -1; + if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning) + xBeginning = 1; + else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End) + xEnd = -1; + } else if (selectionBehavior == QAbstractItemView::SelectColumns) { + xBeginning = 1; xEnd = -1; + if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning) + yBeginning = 1; + else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End) + yEnd = -1; + } + highlightRect = option->rect.adjusted(xBeginning, yBeginning, xEnd, yEnd); + } + } + bool tableView = false; + if (itemView && qobject_cast<const QTableView *>(widget)) + tableView = true; + + QS60StylePrivate::SkinElements element; + QRect elementRect = option->rect; + + //draw item is drawn as pressed, if it already has focus. + if (isPressed && (hasFocus || isSelected)) { + element = tableView ? QS60StylePrivate::SE_TableItemPressed : QS60StylePrivate::SE_ListItemPressed; + } else if (hasFocus || (isSelected && selectionBehavior != QAbstractItemView::SelectItems)) { + element = QS60StylePrivate::SE_ListHighlight; + elementRect = highlightRect; + } + QS60StylePrivate::drawSkinElement(element, painter, elementRect, flags); + } else { + QCommonStyle::drawPrimitive(element, option, painter, widget); + } + } break; #endif //QT_NO_ITEMVIEWS @@ -3067,8 +3100,11 @@ void QS60Style::unpolish(QWidget *widget) void QS60Style::polish(QApplication *application) { Q_D(QS60Style); + QCommonStyle::polish(qApp); d->m_originalPalette = application->palette(); d->setThemePalette(application); + if (QS60StylePrivate::isTouchSupported()) + qApp->installEventFilter(this); } /*! @@ -3077,10 +3113,14 @@ void QS60Style::polish(QApplication *application) void QS60Style::unpolish(QApplication *application) { Q_UNUSED(application) + Q_D(QS60Style); + QCommonStyle::unpolish(qApp); const QPalette newPalette = QApplication::style()->standardPalette(); QApplication::setPalette(newPalette); QApplicationPrivate::setSystemPalette(d->m_originalPalette); + if (QS60StylePrivate::isTouchSupported()) + qApp->removeEventFilter(this); } /*! @@ -3227,9 +3267,40 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, */ bool QS60Style::eventFilter(QObject *object, QEvent *event) { + Q_D(QS60Style); + switch(event->type()) { + case QEvent::MouseButtonPress: { + QWidget *w = QApplication::widgetAt(QCursor::pos()); + if (w) { + QWidget *focusW = w->focusProxy(); + if (qobject_cast<QAbstractItemView *>(focusW) || + qobject_cast<QRadioButton *>(focusW) || + qobject_cast<QCheckBox *>(focusW)) + d->m_pressedWidget = focusW; + else if (qobject_cast<QAbstractItemView *>(w)|| + qobject_cast<QRadioButton *>(w) || + qobject_cast<QCheckBox *>(w)) + d->m_pressedWidget = w; + + if ( d->m_pressedWidget) + d->m_pressedWidget->update(); + } + break; + } + case QEvent::MouseButtonRelease: { + const QWidget *w = QApplication::widgetAt(QCursor::pos()); + if (w && d->m_pressedWidget) { + d->m_pressedWidget->update(); + d->m_pressedWidget = 0; + } + break; + } + default: + break; + } + #ifdef Q_WS_S60 #ifndef QT_NO_PROGRESSBAR - Q_D(QS60Style); switch(event->type()) { case QEvent::StyleChange: case QEvent::Show: @@ -3250,7 +3321,7 @@ bool QS60Style::eventFilter(QObject *object, QEvent *event) } #endif // QT_NO_PROGRESSBAR #endif // Q_WS_S60 - return QStyle::eventFilter(object, event); + return QCommonStyle::eventFilter(object, event); } /*! diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index 6ce4960..9dd3810 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -293,6 +293,24 @@ public: SP_QsnFrButtonSideLInactive, SP_QsnFrButtonSideRInactive, SP_QsnFrButtonCenterInactive, + SP_QsnFrGridCornerTlPressed, // Pressed table item + SP_QsnFrGridCornerTrPressed, + SP_QsnFrGridCornerBlPressed, + SP_QsnFrGridCornerBrPressed, + SP_QsnFrGridSideTPressed, + SP_QsnFrGridSideBPressed, + SP_QsnFrGridSideLPressed, + SP_QsnFrGridSideRPressed, + SP_QsnFrGridCenterPressed, + SP_QsnFrListCornerTlPressed, // Pressed list item + SP_QsnFrListCornerTrPressed, + SP_QsnFrListCornerBlPressed, + SP_QsnFrListCornerBrPressed, + SP_QsnFrListSideTPressed, + SP_QsnFrListSideBPressed, + SP_QsnFrListSideLPressed, + SP_QsnFrListSideRPressed, + SP_QsnFrListPressed, }; enum ColorLists { @@ -424,7 +442,9 @@ public: SE_ScrollBarHandlePressedVertical, SE_ButtonInactive, SE_Editor, - SE_DropArea + SE_DropArea, + SE_TableItemPressed, + SE_ListItemPressed, }; enum SkinFrameElements { @@ -442,6 +462,8 @@ public: SF_ToolBarButtonPressed, SF_PanelBackground, SF_ButtonInactive, + SF_TableItemPressed, + SF_ListItemPressed, }; enum SkinElementFlag { @@ -496,6 +518,7 @@ public: static bool isToolBarBackground(); static bool hasSliderGrooveGraphic(); static bool isSingleClickUi(); + static bool isWidgetPressed(const QWidget *widget); // calculates average color based on button skin graphics (minus borders). QColor colorFromFrameGraphics(SkinFrameElements frame) const; @@ -593,6 +616,8 @@ private: QPointer<QFocusFrame> m_focusFrame; static qint64 m_webPaletteKey; + static QPointer<QWidget> m_pressedWidget; + #ifdef Q_WS_S60 //list of progress bars having animation running QList<QProgressBar *> m_bars; diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 97cf919..74da51e 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -377,6 +377,27 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { /* SP_QsnFrButtonSideRInactive */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b8}, /* SP_QsnFrButtonCenterInactive */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_3_X, EAknsMajorSkin, 0x21b9}, + // No pressed down grid in 3.1/3.2 + /* SP_QsnFrGridCornerTlPressed */ {KAknsIIDQsnFrGridCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2681}, /*KAknsIIDQsnFrGridCornerTlPressed*/ + /* SP_QsnFrGridCornerTrPressed */ {KAknsIIDQsnFrGridCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2682}, + /* SP_QsnFrGridCornerBlPressed */ {KAknsIIDQsnFrGridCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2683}, + /* SP_QsnFrGridCornerBrPressed */ {KAknsIIDQsnFrGridCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2684}, + /* SP_QsnFrGridSideTPressed */ {KAknsIIDQsnFrGridSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2685}, + /* SP_QsnFrGridSideBPressed */ {KAknsIIDQsnFrGridSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2686}, + /* SP_QsnFrGridSideLPressed */ {KAknsIIDQsnFrGridSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2687}, + /* SP_QsnFrGridSideRPressed */ {KAknsIIDQsnFrGridSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2688}, + /* SP_QsnFrGridCenterPressed */ {KAknsIIDQsnFrGridCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2689}, + + // No pressed down list in 3.1/3.2 + /* SP_QsnFrListCornerTlPressed */ {KAknsIIDQsnFrListCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268b}, /*KAknsIIDQsnFrListCornerTlPressed*/ + /* SP_QsnFrListCornerTrPressed */ {KAknsIIDQsnFrListCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268c}, + /* SP_QsnFrListCornerBlPressed */ {KAknsIIDQsnFrListCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268d}, + /* SP_QsnFrListCornerBrPressed */ {KAknsIIDQsnFrListCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268e}, + /* SP_QsnFrListSideTPressed */ {KAknsIIDQsnFrListSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268f}, + /* SP_QsnFrListSideBPressed */ {KAknsIIDQsnFrListSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2690}, + /* SP_QsnFrListSideLPressed */ {KAknsIIDQsnFrListSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2691}, + /* SP_QsnFrListSideRPressed */ {KAknsIIDQsnFrListSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2692}, + /* SP_QsnFrListPressed */ {KAknsIIDQsnFrList, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2693}, }; QPixmap QS60StyleModeSpecifics::skinnedGraphics( diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp index 10bab01..c99e870 100644 --- a/src/multimedia/audio/qaudioinput.cpp +++ b/src/multimedia/audio/qaudioinput.cpp @@ -146,6 +146,20 @@ QT_BEGIN_NAMESPACE \snippet doc/src/snippets/audio/main.cpp 0 \sa QAudioOutput, QAudioDeviceInfo + + \section1 Symbian Platform Security Requirements + + On Symbian, processes which use this class must have the + \c UserEnvironment platform security capability. If the client + process lacks this capability, calls to either overload of start() + will fail. + This failure is indicated by the QAudioInput object setting + its error() value to \l{QAudio::OpenError} and then emitting a + \l{stateChanged()}{stateChanged}(\l{QAudio::StoppedState}) signal. + + Platform security capabilities are added via the + \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY} + qmake variable. */ /*! @@ -197,6 +211,8 @@ QAudioInput::~QAudioInput() If a problem occurs during this process the error() is set to QAudio::OpenError, state() is set to QAudio::StoppedState and stateChanged() signal is emitted. + \sa {Symbian Platform Security Requirements} + \sa QIODevice */ @@ -217,6 +233,8 @@ void QAudioInput::start(QIODevice* device) If a problem occurs during this process the error() is set to QAudio::OpenError, state() is set to QAudio::StoppedState and stateChanged() signal is emitted. + \sa {Symbian Platform Security Requirements} + \sa QIODevice */ diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index efeef4e..7f6df0a 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -2309,6 +2309,12 @@ void QFtpPrivate::_q_piFinished(const QString&) void QFtpPrivate::_q_piError(int errorCode, const QString &text) { Q_Q(QFtp); + + if (pending.isEmpty()) { + qWarning() << "QFtpPrivate::_q_piError was called without pending command!"; + return; + } + QFtpCommand *c = pending.first(); // non-fatal errors diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index bc7684a..83b7d4c 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -690,6 +690,8 @@ void QHttpNetworkConnectionChannel::detectPipeliningSupport() && (serverHeaderField = reply->headerField("Server"), !serverHeaderField.contains("Microsoft-IIS/4.")) && (!serverHeaderField.contains("Microsoft-IIS/5.")) && (!serverHeaderField.contains("Netscape-Enterprise/3.")) + // this is adpoted from the knowledge of the Nokia 7.x browser team (DEF143319) + && (!serverHeaderField.contains("WebLogic")) ) { pipeliningSupported = QHttpNetworkConnectionChannel::PipeliningProbablySupported; } else { diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 03b7192..acf894c 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -138,6 +138,16 @@ static void ensureInitialized() can be: \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 1 + \section1 Symbian Platform Security Requirements + + On Symbian, processes which use this class must have the + \c NetworkServices platform security capability. If the client + process lacks this capability, operations will result in a panic. + + Platform security capabilities are added via the + \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY} + qmake variable. + \sa QNetworkRequest, QNetworkReply, QNetworkProxy */ diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 9a2c349..354c944 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -601,10 +601,15 @@ bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const // Peek 0 bytes into the next message. The size of the message may // well be 0, so we can't check recvfrom's return value. ssize_t readBytes; +#ifdef Q_OS_SYMBIAN + char c; + readBytes = ::recvfrom(socketDescriptor, &c, 1, MSG_PEEK, &storage.a, &storageSize); +#else do { char c; readBytes = ::recvfrom(socketDescriptor, &c, 1, MSG_PEEK, &storage.a, &storageSize); } while (readBytes == -1 && errno == EINTR); +#endif // If there's no error, or if our buffer was too small, there must be a // pending datagram. @@ -661,11 +666,17 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS sz = sizeof(aa); ssize_t recvFromResult = 0; +#ifdef Q_OS_SYMBIAN + char c; + recvFromResult = ::recvfrom(socketDescriptor, maxSize ? data : &c, maxSize ? maxSize : 1, + 0, &aa.a, &sz); +#else do { char c; recvFromResult = ::recvfrom(socketDescriptor, maxSize ? data : &c, maxSize ? maxSize : 1, 0, &aa.a, &sz); } while (recvFromResult == -1 && errno == EINTR); +#endif if (recvFromResult == -1) { setError(QAbstractSocket::NetworkError, ReceiveDatagramErrorString); @@ -832,17 +843,17 @@ qint64 QNativeSocketEnginePrivate::nativeWrite(const char *data, qint64 len) // ignore the SIGPIPE signal qt_ignore_sigpipe(); - // loop while ::write() returns -1 and errno == EINTR, in case - // of an interrupting signal. ssize_t writtenBytes; - do { #ifdef Q_OS_SYMBIAN - writtenBytes = ::write(socketDescriptor, data, len); + // Symbian does not support signals natively and Open C returns EINTR when moving to offline + writtenBytes = ::write(socketDescriptor, data, len); #else + // loop while ::write() returns -1 and errno == EINTR, in case + // of an interrupting signal. + do { writtenBytes = qt_safe_write(socketDescriptor, data, len); -#endif - // writtenBytes = QT_WRITE(socketDescriptor, data, len); ### TODO S60: Should this line be removed or the one above it? } while (writtenBytes < 0 && errno == EINTR); +#endif if (writtenBytes < 0) { switch (errno) { @@ -882,13 +893,13 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxSize) } ssize_t r = 0; - do { #ifdef Q_OS_SYMBIAN - r = ::read(socketDescriptor, data, maxSize); + r = ::read(socketDescriptor, data, maxSize); #else + do { r = qt_safe_read(socketDescriptor, data, maxSize); -#endif } while (r == -1 && errno == EINTR); +#endif if (r < 0) { r = -1; diff --git a/src/network/socket/qtcpserver.cpp b/src/network/socket/qtcpserver.cpp index 404eee7..932126d 100644 --- a/src/network/socket/qtcpserver.cpp +++ b/src/network/socket/qtcpserver.cpp @@ -79,6 +79,16 @@ use waitForNewConnection(), which blocks until either a connection is available or a timeout expires. + \section1 Symbian Platform Security Requirements + + On Symbian, processes which use this class must have the + \c NetworkServices platform security capability. If the client + process lacks this capability, it will lead to a panic. + + Platform security capabilities are added via the + \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY} + qmake variable. + \sa QTcpSocket, {Fortune Server Example}, {Threaded Fortune Server Example}, {Loopback Example}, {Torrent Example} */ diff --git a/src/network/socket/qtcpsocket.cpp b/src/network/socket/qtcpsocket.cpp index b1c7c1c..70852a5 100644 --- a/src/network/socket/qtcpsocket.cpp +++ b/src/network/socket/qtcpsocket.cpp @@ -60,6 +60,16 @@ \bold{Note:} TCP sockets cannot be opened in QIODevice::Unbuffered mode. + \section1 Symbian Platform Security Requirements + + On Symbian, processes which use this class must have the + \c NetworkServices platform security capability. If the client + process lacks this capability, it will result in a panic. + + Platform security capabilities are added via the + \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY} + qmake variable. + \sa QTcpServer, QUdpSocket, QFtp, QNetworkAccessManager, {Fortune Server Example}, {Fortune Client Example}, {Threaded Fortune Server Example}, {Blocking Fortune Client Example}, diff --git a/src/network/socket/qudpsocket.cpp b/src/network/socket/qudpsocket.cpp index e208904..d5366d3 100644 --- a/src/network/socket/qudpsocket.cpp +++ b/src/network/socket/qudpsocket.cpp @@ -86,6 +86,16 @@ \l{network/broadcastreceiver}{Broadcast Receiver} examples illustrate how to use QUdpSocket in applications. + \section1 Symbian Platform Security Requirements + + On Symbian, processes which use this class must have the + \c NetworkServices platform security capability. If the client + process lacks this capability, operations will result in a panic. + + Platform security capabilities are added via the + \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY} + qmake variable. + \sa QTcpSocket */ diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 9623570..7ad471c 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -156,6 +156,16 @@ is being encrypted and encryptedBytesWritten() will get emitted as soon as data has been written to the TCP socket. + \section1 Symbian Platform Security Requirements + + On Symbian, processes which use this class must have the + \c NetworkServices platform security capability. If the client + process lacks this capability, operations will fail. + + Platform security capabilities are added via the + \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY} + qmake variable. + \sa QSslCertificate, QSslCipher, QSslError */ diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 94cc9d2..8620e00 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -742,7 +742,7 @@ bool q_resolveOpenSslSymbols() bool q_resolveOpenSslSymbols() { -#ifdef QT_NO_SSL +#ifdef QT_NO_OPENSSL return false; #endif return true; diff --git a/src/s60installs/qt.iby b/src/s60installs/qt.iby index ec019e2..595734d 100644 --- a/src/s60installs/qt.iby +++ b/src/s60installs/qt.iby @@ -19,7 +19,6 @@ file=ABI_DIR\BUILD_DIR\QtWebKit.dll SHARED_LIB_DIR\QtWebKit.dll file=ABI_DIR\BUILD_DIR\phonon.dll SHARED_LIB_DIR\phonon.dll file=ABI_DIR\BUILD_DIR\QtMultimedia.dll SHARED_LIB_DIR\QtMultimedia.dll file=ABI_DIR\BUILD_DIR\QtXmlPatterns.dll SHARED_LIB_DIR\QtXmlPatterns.dll -file=ABI_DIR\BUILD_DIR\QtDeclarative.dll SHARED_LIB_DIR\QtDeclarative.dll // imageformats file=ABI_DIR\BUILD_DIR\qgif.dll SHARED_LIB_DIR\qgif.dll diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 2422108..9bd98f1 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -41,6 +41,7 @@ #include <QtCore/qstringlist.h> #include <QtCore/qmetaobject.h> +#include "CodeBlock.h" #include "Error.h" #include "JSArray.h" #include "JSLock.h" @@ -662,7 +663,7 @@ JSC::JSValue JSC_HOST_CALL functionQsTranslate(JSC::ExecState *exec, JSC::JSObje else if (encStr == QLatin1String("UnicodeUTF8")) encoding = QCoreApplication::UnicodeUTF8; else - return JSC::throwError(exec, JSC::GeneralError, QString::fromLatin1("qsTranslate(): invalid encoding '%s'").arg(encStr)); + return JSC::throwError(exec, JSC::GeneralError, QString::fromLatin1("qsTranslate(): invalid encoding '%0'").arg(encStr)); } int n = -1; if (args.size() > 4) @@ -696,12 +697,21 @@ JSC::JSValue JSC_HOST_CALL functionQsTr(JSC::ExecState *exec, JSC::JSObject*, JS if ((args.size() > 1) && !args.at(1).isString()) return JSC::throwError(exec, JSC::GeneralError, "qsTr(): second argument (comment) must be a string"); if ((args.size() > 2) && !args.at(2).isNumber()) - return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): third argument (n) must be a number"); + return JSC::throwError(exec, JSC::GeneralError, "qsTr(): third argument (n) must be a number"); #ifndef QT_NO_QOBJECT QString context; - QScriptContext *ctx = QScriptEnginePrivate::contextForFrame(exec); - if (ctx && ctx->parentContext()) - context = QFileInfo(QScriptContextInfo(ctx->parentContext()).fileName()).baseName(); + // The first non-empty source URL in the call stack determines the translation context. + { + JSC::ExecState *frame = exec->removeHostCallFrameFlag(); + while (frame) { + if (frame->codeBlock() && frame->codeBlock()->source() + && !frame->codeBlock()->source()->url().isEmpty()) { + context = QFileInfo(frame->codeBlock()->source()->url()).baseName(); + break; + } + frame = frame->callerFrame()->removeHostCallFrameFlag(); + } + } #endif QString text(args.at(0).toString(exec)); #ifndef QT_NO_QOBJECT diff --git a/tests/auto/qftp/tst_qftp.cpp b/tests/auto/qftp/tst_qftp.cpp index 638c810..2a42d6d 100644 --- a/tests/auto/qftp/tst_qftp.cpp +++ b/tests/auto/qftp/tst_qftp.cpp @@ -123,6 +123,8 @@ private slots: void doneSignal(); void queueMoreCommandsInDoneSlot(); + void qtbug7359Crash(); + protected slots: void stateChanged( int ); void listInfo( const QUrlInfo & ); @@ -2052,6 +2054,30 @@ void tst_QFtp::cdUpSlot(bool error) } } +void tst_QFtp::qtbug7359Crash() +{ + QFtp ftp; + ftp.connectToHost("127.0.0.1"); + + QTime t; + int elapsed; + + t.start(); + while ((elapsed = t.elapsed()) < 200) + QCoreApplication::processEvents(QEventLoop::AllEvents, 200 - elapsed); + + ftp.close(); + t.restart(); + while ((elapsed = t.elapsed()) < 1000) + QCoreApplication::processEvents(QEventLoop::AllEvents, 1000 - elapsed); + + ftp.connectToHost("127.0.0.1"); + + t.restart(); + while ((elapsed = t.elapsed()) < 2000) + QCoreApplication::processEvents(QEventLoop::AllEvents, 2000 - elapsed); +} + QTEST_MAIN(tst_QFtp) #include "tst_qftp.moc" diff --git a/tests/auto/qhttpsocketengine/tst_qhttpsocketengine.cpp b/tests/auto/qhttpsocketengine/tst_qhttpsocketengine.cpp index 3a3ea79..f86ba63 100644 --- a/tests/auto/qhttpsocketengine/tst_qhttpsocketengine.cpp +++ b/tests/auto/qhttpsocketengine/tst_qhttpsocketengine.cpp @@ -641,7 +641,7 @@ void tst_QHttpSocketEngine::downloadBigFile() QByteArray hostName = QtNetworkSettings::serverName().toLatin1(); QVERIFY(tmpSocket->state() == QAbstractSocket::ConnectedState); - QVERIFY(tmpSocket->write("GET /mediumfile HTTP/1.0\r\n") > 0); + QVERIFY(tmpSocket->write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0); QVERIFY(tmpSocket->write("Host: ") > 0); QVERIFY(tmpSocket->write(hostName.data()) > 0); QVERIFY(tmpSocket->write("\r\n") > 0); diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 890983e..038610d 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -4013,7 +4013,7 @@ public slots: } } void startOne() { - QUrl url = "http://" + QtNetworkSettings::serverName() + "/gif/fluke.gif"; + QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/fluke.gif"; QNetworkRequest request(url); QNetworkReply *reply = manager.get(request); reply->setParent(this); diff --git a/tests/auto/qscriptengine/qscriptengine.pro b/tests/auto/qscriptengine/qscriptengine.pro index dd058a4..7d0f5d0 100644 --- a/tests/auto/qscriptengine/qscriptengine.pro +++ b/tests/auto/qscriptengine/qscriptengine.pro @@ -1,6 +1,7 @@ load(qttest_p4) QT = core gui script SOURCES += tst_qscriptengine.cpp +RESOURCES += qscriptengine.qrc wince* { DEFINES += SRCDIR=\\\"./\\\" diff --git a/tests/auto/qscriptengine/qscriptengine.qrc b/tests/auto/qscriptengine/qscriptengine.qrc new file mode 100644 index 0000000..b87f985 --- /dev/null +++ b/tests/auto/qscriptengine/qscriptengine.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>translations/translatable_la.qm</file> +</qresource> +</RCC> diff --git a/tests/auto/qscriptengine/translatable.js b/tests/auto/qscriptengine/translatable.js new file mode 100644 index 0000000..0c948e7 --- /dev/null +++ b/tests/auto/qscriptengine/translatable.js @@ -0,0 +1,7 @@ +qsTr("One"); +qsTranslate("FooContext", "Two"); + +var greeting_strings = [ + QT_TR_NOOP("Hello"), + QT_TRANSLATE_NOOP("FooContext", "Goodbye") +]; diff --git a/tests/auto/qscriptengine/translations/translatable_la.qm b/tests/auto/qscriptengine/translations/translatable_la.qm Binary files differnew file mode 100644 index 0000000..03fcc52 --- /dev/null +++ b/tests/auto/qscriptengine/translations/translatable_la.qm diff --git a/tests/auto/qscriptengine/translations/translatable_la.ts b/tests/auto/qscriptengine/translations/translatable_la.ts new file mode 100644 index 0000000..3f631de --- /dev/null +++ b/tests/auto/qscriptengine/translations/translatable_la.ts @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="nb_NO"> +<context> + <name>FooContext</name> + <message> + <location filename="translatable.js" line="2"/> + <source>Two</source> + <translation>To</translation> + </message> + <message> + <location filename="translatable.js" line="6"/> + <source>Goodbye</source> + <translation>Farvel</translation> + </message> +</context> +<context> + <name>translatable</name> + <message> + <location filename="translatable.js" line="1"/> + <source>One</source> + <translation>En</translation> + </message> + <message> + <location filename="translatable.js" line="5"/> + <source>Hello</source> + <translation>Hallo</translation> + </message> + <message> + <source>Goodbye</source> + <translation type="obsolete">Farvel</translation> + </message> +</context> +</TS> diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index f556fa1..674e502 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -154,6 +154,9 @@ private slots: void incDecNonObjectProperty(); void installTranslatorFunctions_data(); void installTranslatorFunctions(); + void translateScript(); + void translateWithInvalidArgs_data(); + void translateWithInvalidArgs(); void functionScopes(); void nativeFunctionScopes(); void evaluateProgram(); @@ -4314,6 +4317,85 @@ void tst_QScriptEngine::installTranslatorFunctions() } } +void tst_QScriptEngine::translateScript() +{ + QScriptEngine engine; + + QTranslator translator; + translator.load(":/translations/translatable_la"); + QCoreApplication::instance()->installTranslator(&translator); + engine.installTranslatorFunctions(); + + QString fileName = QString::fromLatin1("translatable.js"); + // Top-level + QCOMPARE(engine.evaluate("qsTr('One')", fileName).toString(), QString::fromLatin1("En")); + QCOMPARE(engine.evaluate("qsTr('Hello')", fileName).toString(), QString::fromLatin1("Hallo")); + // From function + QCOMPARE(engine.evaluate("(function() { return qsTr('One'); })()", fileName).toString(), QString::fromLatin1("En")); + QCOMPARE(engine.evaluate("(function() { return qsTr('Hello'); })()", fileName).toString(), QString::fromLatin1("Hallo")); + // From eval + QCOMPARE(engine.evaluate("eval('qsTr(\\'One\\')')", fileName).toString(), QString::fromLatin1("En")); + QCOMPARE(engine.evaluate("eval('qsTr(\\'Hello\\')')", fileName).toString(), QString::fromLatin1("Hallo")); + + QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Two')", fileName).toString(), QString::fromLatin1("To")); + QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Goodbye')", fileName).toString(), QString::fromLatin1("Farvel")); + // From eval + QCOMPARE(engine.evaluate("eval('qsTranslate(\\'FooContext\\', \\'Two\\')')", fileName).toString(), QString::fromLatin1("To")); + QCOMPARE(engine.evaluate("eval('qsTranslate(\\'FooContext\\', \\'Goodbye\\')')", fileName).toString(), QString::fromLatin1("Farvel")); + + QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Goodbye', '', 'UnicodeUTF8')", fileName).toString(), QString::fromLatin1("Farvel")); + + QVERIFY(engine.evaluate("QT_TR_NOOP()").isUndefined()); + QCOMPARE(engine.evaluate("QT_TR_NOOP('One')").toString(), QString::fromLatin1("One")); + + QVERIFY(engine.evaluate("QT_TRANSLATE_NOOP()").isUndefined()); + QVERIFY(engine.evaluate("QT_TRANSLATE_NOOP('FooContext')").isUndefined()); + QCOMPARE(engine.evaluate("QT_TRANSLATE_NOOP('FooContext', 'Two')").toString(), QString::fromLatin1("Two")); + + // Don't exist in translation + QCOMPARE(engine.evaluate("qsTr('Three')", fileName).toString(), QString::fromLatin1("Three")); + QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'So long')", fileName).toString(), QString::fromLatin1("So long")); + QCOMPARE(engine.evaluate("qsTranslate('BarContext', 'Goodbye')", fileName).toString(), QString::fromLatin1("Goodbye")); + + // From C++ + // There is no context, but it shouldn't crash + QCOMPARE(engine.globalObject().property("qsTr").call( + QScriptValue(), QScriptValueList() << "One").toString(), QString::fromLatin1("One")); + + QCoreApplication::instance()->removeTranslator(&translator); +} + +void tst_QScriptEngine::translateWithInvalidArgs_data() +{ + QTest::addColumn<QString>("expression"); + QTest::addColumn<QString>("expectedError"); + + QTest::newRow("qsTr()") << "qsTr()" << "Error: qsTr() requires at least one argument"; + QTest::newRow("qsTr(123)") << "qsTr(123)" << "Error: qsTr(): first argument (text) must be a string"; + QTest::newRow("qsTr('foo', 123)") << "qsTr('foo', 123)" << "Error: qsTr(): second argument (comment) must be a string"; + QTest::newRow("qsTr('foo', 'bar', 'baz')") << "qsTr('foo', 'bar', 'baz')" << "Error: qsTr(): third argument (n) must be a number"; + QTest::newRow("qsTr('foo', 'bar', true)") << "qsTr('foo', 'bar', true)" << "Error: qsTr(): third argument (n) must be a number"; + + QTest::newRow("qsTranslate()") << "qsTranslate()" << "Error: qsTranslate() requires at least two arguments"; + QTest::newRow("qsTranslate('foo')") << "qsTranslate('foo')" << "Error: qsTranslate() requires at least two arguments"; + QTest::newRow("qsTranslate('foo', 123)") << "qsTranslate('foo', 123)" << "Error: qsTranslate(): second argument (text) must be a string"; + QTest::newRow("qsTranslate('foo', 'bar', 123)") << "qsTranslate('foo', 'bar', 123)" << "Error: qsTranslate(): third argument (comment) must be a string"; + QTest::newRow("qsTranslate('foo', 'bar', 'baz', 123)") << "qsTranslate('foo', 'bar', 'baz', 123)" << "Error: qsTranslate(): fourth argument (encoding) must be a string"; + QTest::newRow("qsTranslate('foo', 'bar', 'baz', 'zab', 'rab')") << "qsTranslate('foo', 'bar', 'baz', 'zab', 'rab')" << "Error: qsTranslate(): fifth argument (n) must be a number"; + QTest::newRow("qsTranslate('foo', 'bar', 'baz', 'zab', 123)") << "qsTranslate('foo', 'bar', 'baz', 'zab', 123)" << "Error: qsTranslate(): invalid encoding 'zab'"; +} + +void tst_QScriptEngine::translateWithInvalidArgs() +{ + QFETCH(QString, expression); + QFETCH(QString, expectedError); + QScriptEngine engine; + engine.installTranslatorFunctions(); + QScriptValue result = engine.evaluate(expression); + QVERIFY(result.isError()); + QCOMPARE(result.toString(), expectedError); +} + void tst_QScriptEngine::functionScopes() { QScriptEngine eng; diff --git a/tests/auto/qsocks5socketengine/tst_qsocks5socketengine.cpp b/tests/auto/qsocks5socketengine/tst_qsocks5socketengine.cpp index a679765..8f0cbc3 100644 --- a/tests/auto/qsocks5socketengine/tst_qsocks5socketengine.cpp +++ b/tests/auto/qsocks5socketengine/tst_qsocks5socketengine.cpp @@ -780,7 +780,7 @@ void tst_QSocks5SocketEngine::downloadBigFile() QByteArray hostName = QtNetworkSettings::serverName().toLatin1(); QVERIFY(tmpSocket->state() == QAbstractSocket::ConnectedState); - QVERIFY(tmpSocket->write("GET /mediumfile HTTP/1.0\r\n") > 0); + QVERIFY(tmpSocket->write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0); QVERIFY(tmpSocket->write("HOST: ") > 0); QVERIFY(tmpSocket->write(hostName.data()) > 0); QVERIFY(tmpSocket->write("\r\n") > 0); diff --git a/tests/auto/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/qtcpsocket/tst_qtcpsocket.cpp index ef7ff83..c6e4758 100644 --- a/tests/auto/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/qtcpsocket/tst_qtcpsocket.cpp @@ -1116,7 +1116,7 @@ void tst_QTcpSocket::downloadBigFile() QByteArray hostName = QtNetworkSettings::serverName().toLatin1(); QVERIFY(tmpSocket->state() == QAbstractSocket::ConnectedState); - QVERIFY(tmpSocket->write("GET /mediumfile HTTP/1.0\r\n") > 0); + QVERIFY(tmpSocket->write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0); QVERIFY(tmpSocket->write("HOST: ") > 0); QVERIFY(tmpSocket->write(hostName.data()) > 0); QVERIFY(tmpSocket->write("\r\n") > 0); diff --git a/tools/tools.pro b/tools/tools.pro index 4cff507..f6f2dcd 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -28,7 +28,8 @@ embedded:SUBDIRS += kmap2qmap contains(QT_CONFIG, declarative):SUBDIRS += qmlviewer qmldebugger contains(QT_CONFIG, dbus):SUBDIRS += qdbus -!wince*:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns xmlpatternsvalidator +# We don't need these command line utilities on embedded platforms. +!wince*:!symbian:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns xmlpatternsvalidator embedded: SUBDIRS += makeqpf !wince*:!cross_compile:SUBDIRS += qdoc3 |